package com.pureut.quality.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.bean.BeanUtils;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.quality.domain.QualityInspectionManagement;
import com.pureut.quality.domain.dto.QualityInspectionManagementDto;
import com.pureut.quality.domain.vo.InspectionMarkVo;
import com.pureut.quality.domain.vo.OrderReviewVo;
import com.pureut.quality.domain.vo.QualityInspectionManagementVo;
import com.pureut.quality.mapper.QualityInspectionManagementMapper;
import com.pureut.quality.service.QualityInspectionManagementService;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.vo.SysAuditHistoryVo;
import com.pureut.system.api.vo.SysWorkbenchAuditAgentVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/***
 * 免检管理实现层
 * Author:C
 * Date:2023/02/03 13:54
 * @DESC
 */
@Service
public class QualityInspectionManagementServiceImpl extends ServiceImpl<QualityInspectionManagementMapper, QualityInspectionManagement> implements QualityInspectionManagementService {

    @Resource
    QualityInspectionManagementMapper qualityInspectionManagementMapper;

    @Resource
    FeignService feignService;

    /**
     * 免检管理列表
     *
     * @param qualityInspectionManagementVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<QualityInspectionManagementDto> getManagementList(QualityInspectionManagementVo qualityInspectionManagementVo) {

        //审核状态字典
        List<SysDictData> reviewStatusArray = DictUtils.getDictCache("quality_management_review_status");
        Map<String, String> reviewStatusMap = reviewStatusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //有效期限
        List<SysDictData> validityPeriodArray = DictUtils.getDictCache("quality_validity_period");
        Map<String, String> validityPeriodMap = validityPeriodArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取免检管理列表
        List<QualityInspectionManagementDto> managementList = qualityInspectionManagementMapper.getManagementList(qualityInspectionManagementVo);

        for (QualityInspectionManagementDto entity : managementList) {
            //审核状态
            entity.setReviewStatusDict(reviewStatusMap.get(entity.getReviewStatus()));
            //有效期限
            entity.setValidityPeriodDict(validityPeriodMap.get(entity.getValidityPeriod()));
        }
        return managementList;
    }

    /**
     * 免检管理新增
     *
     * @param qualityInspectionManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(QualityInspectionManagementVo qualityInspectionManagementVo) throws Exception {

        QualityInspectionManagement qualityInspectionManagement = new QualityInspectionManagement();
        BeanUtils.copyProperties(qualityInspectionManagementVo, qualityInspectionManagement);
        //生成一个唯一号码审核时使用
        qualityInspectionManagement.setOnlyNumber(feignService.splitList("ONLYNUMBER"));
        if (qualityInspectionManagementVo.getValidityPeriod() == 2) {
            qualityInspectionManagement.setStatus(2);
            qualityInspectionManagement.setValidityStartTime(null);
            qualityInspectionManagement.setValidityEndTime(null);
        } else {
            //设置状态为关闭
            qualityInspectionManagement.setStatus(2);
        }
        qualityInspectionManagement.setReviewStatus(1);
        qualityInspectionManagement.setDeptId(SecurityUtils.getDeptId());
        qualityInspectionManagement.setCreateTime(new Date());
        qualityInspectionManagement.setCreateBy(SecurityUtils.getUsername());

        //新增审核代办
        SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();

        sysWorkbenchAuditAgentVo.setDocConfig("quality:verifyconfig:freeinspect:examine");
        sysWorkbenchAuditAgentVo.setReceiptName("免检管理");
        sysWorkbenchAuditAgentVo.setReceiptNumber(qualityInspectionManagement.getOnlyNumber());//
        sysWorkbenchAuditAgentVo.setStatus(1);//待审核
        sysWorkbenchAuditAgentVo.setReceiptContent("有单据待审核,请及时审核");

        feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

        return save(qualityInspectionManagement);
    }


    /**
     * 免检管理查看
     *
     * @param id
     * @return
     */
    @Override
    public QualityInspectionManagementDto getViewById(long id) {
        //有效期限
        List<SysDictData> validityPeriodArray = DictUtils.getDictCache("quality_validity_period");
        Map<String, String> validityPeriodMap = validityPeriodArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //免检类型
        List<SysDictData> managementTypeArray = DictUtils.getDictCache("quality_management_type");
        Map<String, String> managementTypeMap = managementTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        QualityInspectionManagementDto viewById = qualityInspectionManagementMapper.getViewById(id);

        viewById.setValidityPeriodDict(validityPeriodMap.get(viewById.getValidityPeriod()));
        viewById.setInspectionExemptionTypeDict(managementTypeMap.get(viewById.getInspectionExemptionType()));
        return viewById;
    }

    /**
     * 免检管理修改
     *
     * @param qualityInspectionManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateManagement(QualityInspectionManagementVo qualityInspectionManagementVo) {
        //获取修改对象
        QualityInspectionManagement byId = getById(qualityInspectionManagementVo.getId());
        if (byId.getReviewStatus() == 1 || byId.getReviewStatus() == 3) {
            //来料免检
            if (byId.getInspectionExemptionType() == 1) {
                byId.setInspectionExemptionType(qualityInspectionManagementVo.getInspectionExemptionType())
                        .setMaterialCode(qualityInspectionManagementVo.getMaterialCode())
                        .setSupplierId(qualityInspectionManagementVo.getSupplierId())
                        .setValidityPeriod(qualityInspectionManagementVo.getValidityPeriod())
                        .setValidityStartTime(qualityInspectionManagementVo.getValidityStartTime())
                        .setValidityEndTime(qualityInspectionManagementVo.getValidityEndTime())
                        .setEnclosureUrl(qualityInspectionManagementVo.getEnclosureUrl())
                        .setReasonApplication(qualityInspectionManagementVo.getReasonApplication());
            } else {
                //委外免检
                byId.setInspectionExemptionType(qualityInspectionManagementVo.getInspectionExemptionType())
                        .setMaterialCode(qualityInspectionManagementVo.getMaterialCode())
                        .setConverterId(qualityInspectionManagementVo.getConverterId())
                        .setValidityPeriod(qualityInspectionManagementVo.getValidityPeriod())
                        .setValidityStartTime(qualityInspectionManagementVo.getValidityStartTime())
                        .setValidityEndTime(qualityInspectionManagementVo.getValidityEndTime())
                        .setEnclosureUrl(qualityInspectionManagementVo.getEnclosureUrl())
                        .setReasonApplication(qualityInspectionManagementVo.getReasonApplication());
            }
            if (byId.getReviewStatus() == 3) {
                //调用审核
                SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
                String perms = "quality:verifyconfig:freeinspect:examine";
                String auditDoc = byId.getOnlyNumber();
                sysAuditHistoryVo.setAuditDoc(auditDoc);
                sysAuditHistoryVo.setPerms(perms);
                AjaxResult history = feignService.editHistory(sysAuditHistoryVo);
                String data = JSON.parseObject(JSON.toJSONString(history.get("msg")), String.class);
                if ("操作成功".equals(data)) {
                    byId.setReviewStatus(1);

                    //修改审核代办状态为已处理
                    feignService.updateStatus(3,byId.getOnlyNumber(),"免检管理");//
                    //新增审核代办
                    SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();

                    sysWorkbenchAuditAgentVo.setDocConfig("quality:verifyconfig:freeinspect:examine");
                    sysWorkbenchAuditAgentVo.setReceiptName("免检管理");
                    sysWorkbenchAuditAgentVo.setReceiptNumber(byId.getOnlyNumber());//
                    sysWorkbenchAuditAgentVo.setStatus(1);//待审核
                    sysWorkbenchAuditAgentVo.setReceiptContent("有单据待审核,请及时审核");

                    feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);



                    return updateById(byId);
                } else {
                    return false;
                }
            }
            return updateById(byId);
        } else {
            throw new GlobalException("只能修改状态为“待审核、未通过”的免检单");
        }
    }

    /**
     * 删除
     *
     * @param idStr
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(String idStr) {
        List<String> ids = Arrays.asList(idStr.split(","));
        if (ids.size() < 1) {
            throw new GlobalException("至少选择一条数据");
        }
        List<QualityInspectionManagement> qualityInspectionManagements = qualityInspectionManagementMapper.selectList(new QueryWrapper<QualityInspectionManagement>().lambda().in(QualityInspectionManagement::getId, idStr));

        List<QualityInspectionManagement> qualityInspectionManagementList = new ArrayList<>();
        for (QualityInspectionManagement entity : qualityInspectionManagements) {
            if (entity.getReviewStatus() == 1 || entity.getReviewStatus() == 3) {
                qualityInspectionManagementList.add(entity);
            } else {
                throw new GlobalException("只能删除待审核、未通过的数据");
            }
        }

        for (QualityInspectionManagement entity : qualityInspectionManagements) {
            feignService.deleteDoc(entity.getOnlyNumber(),"免检管理");
        }
        return qualityInspectionManagementMapper.deleteBatchIds(qualityInspectionManagementList) > 0;
    }

    /**
     * 免检管理审核
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean managementReview(OrderReviewVo orderReviewVo) throws ParseException {

        QualityInspectionManagement qualityInspectionManagement = getById(orderReviewVo.getId());
        if (qualityInspectionManagement.getReviewStatus() == 1 || qualityInspectionManagement.getReviewStatus() == 4) {

            String perms = "quality:verifyconfig:freeinspect:examine";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = qualityInspectionManagement.getOnlyNumber();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = SecurityUtils.getUserId();
            AjaxResult sequence = feignService.getSequenceTwo(perms, 4, isAdopt, auditRemarks, auditDoc, userId);
            Integer data = JSON.parseObject(JSON.toJSONString(sequence.get("data")), Integer.class);
            if (data == null) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                //同意审核
                if (data == 1) {
                    qualityInspectionManagement.setReviewStatus(2);
                    //判断当审核通过时，有效期限是否为永久
                    if (qualityInspectionManagement.getValidityPeriod() == 2) {
                        qualityInspectionManagement.setStatus(1);
                    } else {
                        //判断当前时间是否在有效时间之内
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        String format = sdf.format(new Date());
                        Date nowTime;
                        nowTime = sdf.parse(format);
                        Date validityStartTime = qualityInspectionManagement.getValidityStartTime();
                        Date validityEndTime = qualityInspectionManagement.getValidityEndTime();
                        boolean trueTime = isTrueTime(nowTime, validityStartTime, validityEndTime);
                        if (trueTime) {
                            qualityInspectionManagement.setStatus(1);
                            qualityInspectionManagement.setReviewStatus(2);
                        } else {
                            qualityInspectionManagement.setStatus(2);
                            qualityInspectionManagement.setReviewStatus(5);
                        }
                    }

                    feignService.updateStatus(3,qualityInspectionManagement.getOnlyNumber(),"免检管理");

                    return updateById(qualityInspectionManagement);
                } else if (data == 2) {
                    qualityInspectionManagement.setReviewStatus(4);
                    return updateById(qualityInspectionManagement);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    qualityInspectionManagement.setReviewStatus(3);

                    //新增审核代办
                    SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();

                    sysWorkbenchAuditAgentVo.setDocConfig("quality:verifyconfig:freeinspect:examine");
                    sysWorkbenchAuditAgentVo.setReceiptName("免检管理");
                    sysWorkbenchAuditAgentVo.setReceiptNumber(qualityInspectionManagement.getOnlyNumber());//
                    sysWorkbenchAuditAgentVo.setStatus(2);//待处理
                    sysWorkbenchAuditAgentVo.setReceiptContent("有单据未通过,请及时查看");

                    sysWorkbenchAuditAgentVo.setPassFlag("1");
                    sysWorkbenchAuditAgentVo.setCreateName(qualityInspectionManagement.getCreateBy());

                    feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

                    return updateById(qualityInspectionManagement);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("状态为待审核和审核中的单据才能进行审核");
        }
    }

    /**
     * 免检管理终止
     *
     * @param idStr
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean stop(String idStr) {
        List<String> ids = Arrays.asList(idStr.split(","));
        if (ids.size() < 1) {
            throw new GlobalException("至少选择一条数据");
        }
        List<QualityInspectionManagement> qualityInspectionManagements = qualityInspectionManagementMapper.selectList(new QueryWrapper<QualityInspectionManagement>().lambda().in(QualityInspectionManagement::getId, idStr));

        List<QualityInspectionManagement> qualityInspectionManagementList = new ArrayList<>();
        for (QualityInspectionManagement entity : qualityInspectionManagements) {
            if (entity.getReviewStatus() == 2) {
                entity.setReviewStatus(6);
                qualityInspectionManagementList.add(entity);
            } else {
                throw new GlobalException("只能终止审核状态为“已通过”的免检单");
            }
        }
        return updateBatchById(qualityInspectionManagementList);
    }

    /**
     * 根据供应商加物料编码/加工商加物料编码获取物料免检状态（feign调用）
     *
     * @param inspectionMarkVo
     * @return
     */
    @Override
    public QualityInspectionManagementDto getInspectionMark(InspectionMarkVo inspectionMarkVo) {
        QualityInspectionManagementDto qualityInspectionManagementDto = new QualityInspectionManagementDto();
        //通过供应商和物料编码查询
        List<QualityInspectionManagementDto> dataBySupplier = qualityInspectionManagementMapper.getDataBySupplier(inspectionMarkVo);
        if (dataBySupplier.size() > 0) {
            qualityInspectionManagementDto = dataBySupplier.get(0);
            return qualityInspectionManagementDto;
        }
        //通过加工商和物料编码查询
        List<QualityInspectionManagementDto> dataByConverter = qualityInspectionManagementMapper.getDataByConverter(inspectionMarkVo);
        if (dataByConverter.size() > 0) {
            qualityInspectionManagementDto = dataByConverter.get(0);
            return qualityInspectionManagementDto;
        }
        return qualityInspectionManagementDto;
    }


    /**
     * 判断当前时间是否在某个时间区间
     */
    public boolean isTrueTime(Date nowTime, Date startTime, Date endTime) {

        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }
}
